#include "work.h"
#include "ui_work.h"
#include "lib/lib.h"
#include "lib/imagefilter.h"
#include <QMessageBox>
#include "lib/superpixelsegmentation.h"
#include "lib/watershedsegmentation.h"
Work::Work(QWidget *parent)
    : QWidget(parent),_path(""),_exportImage(nullptr)
    , ui(new Ui::Work)
{
    ui->setupUi(this);
    /* 设置为只读模式 */
    ui->edit_algorithm->setReadOnly(true);
    ui->edit_run->setReadOnly(true);
    ui->stackedWidget->setCurrentWidget(ui->page);
    connect(this,&Work::SignImageIsNull,this,&Work::SlotImageIsNull);
}

Work::~Work()
{
    delete ui;
}

void Work::SlotImagePath(QString path)
{
    if(path.isEmpty()){
            qDebug()<<"图片打开失败";
        return;
    }
    _path = path;
    QPixmap image(_path);
    // 利用opencv打开图片
    _mat = cv::imread(Lib::QStringToString(_path));
    //保存图片的内容用来保存  MatToQImage  mat与QImage转换。
    _exportImage = Lib::MatToQImage(_mat);
    // 显示图片
    ui->label_image->setPixmap(image);

}

void Work::SlotSaveImagePath(QString path)
{
    if(_mat.empty()){
        emit SignImageIsNull();
        return;
    }
    _exportImage.save(path);
}

void Work::SlotImageIsNull()
{
    QMessageBox::critical(this, tr("警告"), tr("没有导入图片"));
}

void Work::SlotSegmentationString(QString str)
{
    ui->edit_run->appendPlainText(str);
}

void Work::on_pic_transform_clicked()
{
    ui->stackedWidget->setCurrentWidget(ui->page_transform);
    ui->edit_algorithm->clear();
    ui->edit_algorithm->insertPlainText("图像变换");
}


void Work::on_btn_transform_clicked()
{
    cv::Mat result;
    if(_mat.empty()){
        emit SignImageIsNull();
        return;
    }
    if(ui->RGB2HSV->isChecked()){
        cvtColor(_mat,result,cv::COLOR_RGB2HSV);
        ui->edit_algorithm->clear();
        ui->edit_algorithm->insertPlainText("转换为HSV图像");
    }
    if(ui->BGR2GRAY->isChecked()){
        cvtColor(_mat, result, cv::COLOR_BGR2GRAY);
        ui->edit_algorithm->clear();
        ui->edit_algorithm->insertPlainText("转换为灰度图像");

    }
    QImage image = Lib::MatToQImage(result);
    _exportImage = image;
    ui->label_image->setPixmap(QPixmap::fromImage(image));
}




void Work::on_pic_smooth_clicked()
{
    ui->stackedWidget->setCurrentWidget(ui->page_smooth);
    ui->edit_algorithm->clear();
    ui->edit_algorithm->insertPlainText("平滑算法");
}


void Work::on_btn_smooth_clicked()
{
    if(_mat.empty()){
        emit SignImageIsNull();
        return;
    }
    cv::Mat dst = cv::Mat(_mat.size(),_mat.type());
    cv::Size size = cv::Size(5,5);
    //选择滤波核
    if(ui->radio_size1->isChecked()){
        size = cv::Size(3,3);
    }
    if(ui->radio_size2->isChecked()){
        size = cv::Size(5,5);
    }
    //选择平滑算法
    //方框
    if(ui->radio_pane->isChecked()){
        cv::boxFilter(_mat,dst , -1, size, cv::Point(-1, -1), 1);
        ui->edit_algorithm->clear();
        ui->edit_algorithm->insertPlainText("方框算法");
    }
    //均值
    if(ui->radio_mean->isChecked()){
        cv::blur(_mat, dst, size, cv::Point(-1, -1));
        ui->edit_algorithm->clear();
        ui->edit_algorithm->insertPlainText("均值算法");
    }
    // 高斯
    if(ui->radio_gauss->isChecked()){
        cv::GaussianBlur(_mat, dst, size, 0);
        ui->edit_algorithm->clear();
        ui->edit_algorithm->insertPlainText("高斯算法");
    }

    QImage image = Lib::MatToQImage(dst);
    _exportImage = image;
    ui->label_image->setPixmap(QPixmap::fromImage(image));

}


void Work::on_pic_edge_clicked()
{
    ui->stackedWidget->setCurrentWidget(ui->page_edge);
    ui->edit_algorithm->clear();
    ui->edit_algorithm->insertPlainText("边缘检测");
}


void Work::on_btn_edge_clicked()
{
    if(_mat.empty()){
        emit SignImageIsNull();
        return;
    }
    //创建与src同类型和同大小的矩阵
    cv::Mat dst = cv::Mat(_mat.size(),_mat.type());
    //边缘检测
    if(ui->radio_Canny->isChecked()){
        cv::Mat edge, grayImage;
        //将原始图转化为灰度图
        cv::cvtColor(_mat, grayImage, cv::COLOR_BGR2GRAY);
        //先使用3*3内核来降噪
        cv::blur(grayImage, edge, cv::Size(3, 3));
        //运行canny算子
        cv::Canny(edge, dst, 3, 9, 3);
        // Canny(edge, edge, 3, 9, 3);
        // imshow("边缘提取效果", edge);
        ui->edit_algorithm->clear();
        ui->edit_algorithm->insertPlainText("Canny");
    }
    if(ui->radio_Sobel->isChecked()){
        cv::Mat grad_x, grad_y;
        cv::Mat abs_grad_x, abs_grad_y;

        //求x方向梯度
        cv::Sobel(_mat, grad_x, CV_16S, 1, 0, 3, 1, 1,cv::BORDER_DEFAULT);
        cv::convertScaleAbs(grad_x, abs_grad_x);
        // imshow("x方向soble", abs_grad_x);

        //求y方向梯度
        cv::Sobel(_mat, grad_y,CV_16S,0, 1,3, 1, 1, cv::BORDER_DEFAULT);
        cv::convertScaleAbs(grad_y,abs_grad_y);
        // imshow("y向soble", abs_grad_y);

        //合并梯度
        cv::addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
        // imshow("整体方向soble", dst);
        ui->edit_algorithm->clear();
        ui->edit_algorithm->insertPlainText("Sobel");
    }
    if(ui->radio_Laplacian->isChecked()){
        cv::Mat gray, abs_dst;
        //高斯滤波消除噪声
        cv::GaussianBlur(_mat, dst, cv::Size(3, 3), 0, 0, cv::BORDER_DEFAULT);
        //转换为灰度图
        cv::cvtColor(dst, gray, cv::COLOR_RGB2GRAY);
        //使用Laplace函数
        //第三个参数：目标图像深度；第四个参数：滤波器孔径尺寸；第五个参数：比例因子；第六个参数：表示结果存入目标图
        cv::Laplacian(gray, dst, CV_16S, 3, 1, 0, cv::BORDER_DEFAULT);
        //计算绝对值，并将结果转为8位
        cv::convertScaleAbs(dst, abs_dst);
        dst = abs_dst.clone();
        // imshow("laplace效果图", abs_dst);
        ui->edit_algorithm->clear();
        ui->edit_algorithm->insertPlainText("Laplacian");

    }
    QImage image = Lib::MatToQImage(dst);
    _exportImage = image;
    ui->label_image->setPixmap(QPixmap::fromImage(image));
}


void Work::on_pic_filter_clicked()
{
    ui->stackedWidget->setCurrentWidget(ui->page_filter);
    ui->edit_algorithm->clear();
    ui->edit_algorithm->insertPlainText("滤镜");
    QStringList strList;
    strList<<"原图"<<"浮雕"<<"素描"<<"怀旧"<<"轮廓"<<"模糊"<<"锐化"<<"美颜"<<"水彩";
    ui->filter_comboBox->addItems(strList);
}


void Work::on_btn_filter_clicked()
{
    if(_mat.empty()){
        emit SignImageIsNull();
        return;
    }
    QString algorithm_description = "滤镜";
    Mat dst(_mat.size(),_mat.type());
    int filter_data = ui->filter_comboBox->currentIndex();
    ImageFilter filter;
    // "原图", "浮雕", "素描", "怀旧", "轮廓", "模糊", "锐化", "美颜", "水彩";
    switch (filter_data) {
    // case EnumFilterConfig::OriginalImage:
    //     qDebug()<<a;
    //     break;原图 设置为default
    case EnumFilterConfig::ReliefImage:
        //浮雕
        dst = filter.relief(_mat,150);
        algorithm_description = "滤镜为：浮雕";
        break;
    case EnumFilterConfig::SketchImage:
        //素描
        dst = filter.sketch(_mat);
        algorithm_description = "滤镜为：素描";
        break;
    case EnumFilterConfig::NostalgiaImage:
        //怀旧
        dst = filter.nostalgia(_mat);
        algorithm_description = "滤镜为：怀旧";
        break;
    case EnumFilterConfig::ContourImage:
        // 轮廓
        dst = filter.edge(_mat);
        algorithm_description = "滤镜为：轮廓";
        break;
    case EnumFilterConfig::ObscureImage:
        // 模糊
        dst = filter.blur(_mat);
        algorithm_description = "滤镜为：模糊";
        break;
    case EnumFilterConfig::SharpeningImage:
        // 锐化
        dst = filter.sharp(_mat);
        algorithm_description = "滤镜为：锐化";
        break;
    case EnumFilterConfig::BeautyImage:
        // 美颜
        dst = filter.bifilter(_mat);
        algorithm_description = "滤镜为：美颜";
        break;
    case EnumFilterConfig::WatercolorImage:
        // 水彩
        dst = filter.stylization(_mat);
        algorithm_description = "滤镜为：水彩";
        break;
    default://原图EnumFilterConfig::OriginalImage
        dst = _mat.clone();
        algorithm_description = "设置为：原图";
        break;
    }
    ui->edit_algorithm->clear();
    ui->edit_algorithm->insertPlainText(algorithm_description);
    QImage image = Lib::MatToQImage(dst);
    _exportImage = image;
    ui->label_image->setPixmap(QPixmap::fromImage(image));
}


void Work::on_pic_superpixel_clicked()
{
    ui->stackedWidget->setCurrentWidget(ui->page_execute);
    //设置枚举
    _enumSegmentation = EnumImageSegmentation::SuperpixelImageSegmentation;
    ui->edit_algorithm->clear();
    ui->edit_run->clear();
    ui->edit_algorithm->insertPlainText("超像素分割");
}


void Work::on_btn_execute_clicked()
{
    if(_mat.empty()){
        emit SignImageIsNull();
        return;
    }
    Mat dst;
    //根据枚举选择函数。
    switch (_enumSegmentation) {
    case EnumImageSegmentation::SuperpixelImageSegmentation:
        seg_superpixel = new SuperpixelSegmentation(this);
        connect(seg_superpixel,&SuperpixelSegmentation::SignSegmentationString,this,&Work::SlotSegmentationString);
        dst = seg_superpixel->GetSegmentationImage(_mat);
        break;
    case EnumImageSegmentation::WatershedImageSegmentation:
        seg_watershed = new WatershedSegmentation(this);
        dst = seg_watershed->GetSegmentationImage(_mat);
        break;
    default:
        dst = _mat.clone();
        break;
    }

    QImage image = Lib::MatToQImage(dst);
    _exportImage = image;
    ui->label_image->setPixmap(QPixmap::fromImage(image));
}





void Work::on_pic_watershed_clicked()
{
    ui->stackedWidget->setCurrentWidget(ui->page_execute);
    //设置枚举
    _enumSegmentation = EnumImageSegmentation::WatershedImageSegmentation;
    ui->edit_algorithm->clear();
    ui->edit_run->clear();
    ui->edit_algorithm->insertPlainText("暂未实现，分水岭算法");
}

